package com.kili.file.filter;

import com.alibaba.fastjson.JSONObject;
import com.kili.file.controller.vo.BaseResponse;
import com.kili.file.enums.ResponseCode;
import com.kili.file.utils.CommonValidKit;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

/**
 * FileUploadValidationFilter
 *
 * @author Gordon
 * @version 2019/4/2
 */
@Slf4j
@Setter
public class FileUploadValidationFilter extends OncePerRequestFilter {

    private MultipartResolver multipartResolver;

    public FileUploadValidationFilter(MultipartResolver multipartResolver) {
        this.multipartResolver = multipartResolver;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        log.info("content type {}",request.getContentType());
        MultipartHttpServletRequest multipartRequest = multipartResolver.resolveMultipart(request);
        if (multipartRequest.getFileMap().isEmpty()) {
            responseOutWithJson(response, ResponseCode.FILE_IS_NULL.getMsg(), HttpStatus.BAD_REQUEST);
            return;
        }

        for (Map.Entry<String, MultipartFile> entry : multipartRequest.getFileMap().entrySet()) {
            MultipartFile multipartFile = entry.getValue();
            //   File valid started .this is not recall to client
            try {
                CommonValidKit.unifiedVerificationProcessor(multipartFile);
            } catch (IllegalStateException ex) {
                log.error("Not a normal request flow : {}",
                        multipartFile.getOriginalFilename(), ex);
                responseOutWithJson(response, ex.getMessage(), HttpStatus.BAD_REQUEST);
            } catch (Exception ex) {
                log.error("Filter verifies file is invalid - fileName : {}",
                        multipartFile.getOriginalFilename(), ex);
                responseOutWithJson(response, ResponseCode.INVALID_FILE.getMsg(), HttpStatus.BAD_REQUEST);
                return;
            }
        }
        filterChain.doFilter(request, response);
    }


    private void responseOutWithJson(HttpServletResponse response, String msg, HttpStatus httpStatus) {
        responseOutWithJson(response, msg, httpStatus.value(), null);
    }

    private void responseOutWithJson(HttpServletResponse response, String msg, int httpStatus, String url) {
        String responseJSONString = JSONObject.toJSONString(BaseResponse.of(httpStatus, msg, url));
        response.setStatus(httpStatus);
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        try (PrintWriter out = response.getWriter()) {
            out.append(responseJSONString);
        } catch (IOException e) {
            log.error("ResponseOutWithJson error - responseMsg : {}", msg, e);
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
    }


}
